package org.putrpctorest.expression.spring;

import java.util.ArrayList;
import java.util.List;

import org.apache.cxf.helpers.DOMUtils;
import org.putrpctorest.expression.AbstractExpression;
import org.putrpctorest.expression.RestMethodEntryPoint;
import org.putrpctorest.expression.Routings;
import org.putrpctorest.expression.Expression;
import org.putrpctorest.expression.ExpressionFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

public class ExpressionsNamespaceParser extends AbstractBeanDefinitionParser {

	private final static String REST_ENTRY_POINT_NS = "http://www.example.org/rest-expressions";

	@Override
	protected AbstractBeanDefinition parseInternal(Element element,
			ParserContext parserContext) {
		
		String routingsId= element.getAttribute("id");

		Element entryPointEl = DOMUtils.getFirstChildWithName(element,
				REST_ENTRY_POINT_NS, "rest-service-entry-point");
		

		while (entryPointEl != null) {
			String id = entryPointEl.getAttribute("id");
			String restMethod = entryPointEl.getAttribute("rest-method");
			
			List<Expression> serviceRouters = new ArrayList<Expression>();
			
			Element serviceRouterEl = DOMUtils
			.getFirstChildWithName(entryPointEl, REST_ENTRY_POINT_NS,
					"rest-expression");
			
			while(serviceRouterEl != null) {
				Expression serviceRouter = parseServiceRouter(serviceRouterEl);
				serviceRouters.add(serviceRouter);
				serviceRouterEl = DOMUtils.getNextElement(serviceRouterEl);
			}


			AbstractBeanDefinition bd = BeanDefinitionBuilder
					.rootBeanDefinition(RestMethodEntryPoint.class)
					.addConstructorArgValue(serviceRouters).addPropertyValue("id",restMethod + ".entryPoint").getBeanDefinition();
			parserContext.getRegistry().registerBeanDefinition( restMethod + ".entryPoint",bd);
			entryPointEl = DOMUtils.getNextElement(entryPointEl);
		}

		return BeanDefinitionBuilder.rootBeanDefinition(Routings.class).addPropertyValue("id",routingsId).getBeanDefinition();

	}

	private Expression parseServiceRouter(Element serviceRouterEl) {
		String id = serviceRouterEl.getAttribute("id");
		String type = serviceRouterEl.getAttribute("type");

		Element configEl = DOMUtils.getFirstChildWithName(serviceRouterEl,
				REST_ENTRY_POINT_NS, "config");

		AbstractExpression serviceRouter = ExpressionFactory
				.getInstance().createServiceRouter(type, id, configEl);

		Element subServiceRouterEl = DOMUtils.getFirstChildWithName(
				serviceRouterEl, REST_ENTRY_POINT_NS, "rest-expression");

		if (subServiceRouterEl != null) {
			serviceRouter.addChild(parseServiceRouter(subServiceRouterEl));
			DOMUtils.getNext(subServiceRouterEl);
		}

		return serviceRouter;
	}
}
